/**
 * @file tsk_analy.c
 * @brief tskp库 - 任务参数解析模块实现文件
 * @details
 * 本文件实现了tskp任务调参库的参数解析核心逻辑，包括帧头帧尾提取、ID与命令解析、参数提取、数据推送等功能。
 * 支持多ID、多命令、浮点与整型参数解析，适用于嵌入式、实时系统下的远程指令调参场景。
 *
 * 作者：小傲（个人开发）
 * 邮箱：2655640770@qq.com
 * 版权声明：开源公开，欢迎建议与反馈
 * 日期：2025-09-11
 */

#include"tsk_analy.h"

#ifdef _TSK_TSKP_

/**
 * @brief        // 去除帧头帧尾
 * @param[in]    // array     : 要处理的字符串
 * @param[in]    // frontdata : 帧头字符串
 * @param[in]    // afterdata : 帧尾字符串
 * @return       // bool : 处理结果
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
static bool tsk_movgetdata(char *array, const char *frontdata,const char *afterdata)
{
    char *frontfound =strstr(array,frontdata);
    char *afterfound =strstr(array,afterdata);
    if(frontfound!=NULL&&afterfound!=NULL)
    {
        int frontflag=frontfound-array+strlen(frontdata);
        int afterflag=afterfound-array;
        int len=afterflag-frontflag;
        int i=0;
        for(i=0;i<len;i++)
        {
            array[i]=array[frontflag+i];
        }
        for(i=len+1;i<strlen(array);i++)
        {
            array[i]='0'; 
        }
        array[len]='\0';
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[调试]帧头帧尾提取成功,长度:%d\r\n", len);
            #else
                printf("[Debug] Frame head/tail extracted, len:%d\r\n", len);
            #endif
            fflush(stdout);
        #endif
    }
    else
    {
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[调试]未找到帧头或帧尾\r\n");
            #else
                printf("[Debug] Frame head or tail not found\r\n");
            #endif
            fflush(stdout);
        #endif
        return false;
    }
    return true;
}

/**
 * @brief        // 识别是否为浮点型数据
 * @param[in]    // data : 要识别的数据
 * @return       // bool : true表示是浮点,false表示不是浮点
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
static bool tsk_Iffloat(char data)
{
    if(data=='-'||data=='.'||(data>='0'&&data<='9'))
    {
        return true;
    }
    return false;
}


/**
 * @brief        // 识别是否为整数型数据
 * @param[in]    // data : 要识别的数据
 * @return       // bool : true表示是整数,false表示不是整数
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
static bool tsk_Ifint(char data)
{
    if(data>='0'&&data<='9')
    {
        return true;
    }
    return false;
}

/**
 * @brief        // 转换为小写字母
 * @param[in]    // ch : 要转换的字符
 * @return       // char : 转换结果
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
static char tsk_toupper(char ch)
{
    if(ch>=65&&ch<=90)
    {
        return ch+32;
    }
    else
    {
        return ch;
    }
}

/**
 * @brief        // 识别是否为id数据
 * @param[in]    // data : 要识别的数据
 * @param[in]    // flag : true表示识别为数字,false表示识别非数字
 * @return       // bool : true表示识别成功,false表示识别失败
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
static bool tsk_ifchar_id(char data,bool flag){
    if(flag){
        return tsk_Ifint(data)&&data!='\0';
    }
    else{
        return (!tsk_Ifint(data))&&data!='\0';
    }
}

/**
 * @brief        // 识别是否为浮点型数据
 * @param[in]    // data : 要识别的数据
 * @param[in]    // flag : true表示识别为浮点型数据,false表示识别非浮点型数据
 * @return       // bool : true表示识别成功,false表示识别失败
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
static bool tsk_ifchar_float(char data,bool flag){
    if(flag){
        return tsk_Iffloat(data)&&data!='\0'&&data!=TSK_ID_SPLIT;
    }
    else{
        return (!tsk_Iffloat(data))&&data!='\0'&&data!=TSK_ID_SPLIT;
    }
}

/**
 * @brief        // 获取ID
 * @param[in]    // analy_p : 指向任务解析器结构体的指针
 * @param[in]    // data_pointer : 数据指针
 * @param[in]    // id : 获取到的ID指针
 * @return       // bool : true表示获取成功,false表示获取失败
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
static bool tsk_analy_getid(tsk_analy_t *analy_p,int* data_pointer,uint8_t* id){
    char str_id[4]={0};//id最大到达0-255所以三位即可多一位是个'\0'
    int id_pointer=0;
    while(tsk_ifchar_id(analy_p->data[*data_pointer],false)){
        (*data_pointer)++;
    }
    while (tsk_ifchar_id(analy_p->data[*data_pointer],true)){
        str_id[id_pointer++]=analy_p->data[*data_pointer];
        (*data_pointer)++;
        if(id_pointer>=3){
            while (tsk_ifchar_id(analy_p->data[*data_pointer],true)){
                (*data_pointer)++;
            }
            break;//数据过长无视后续数据
        }
    }
    //获取到有效id
    if(id_pointer!=0){
        str_id[id_pointer]='\0';
        *id=(uint8_t)atoi(str_id);
        if(*id>255){
            #if TSK_TASK_DEBUG
                #if CHINESE_SUPPORT
                    printf("[调试]ID超出范围:%d\r\n", *id);
                #else
                    printf("[Debug] ID out of range: %d\r\n", *id);
                #endif
                fflush(stdout);
            #endif
            return false;
        }
        else{
            #if TSK_TASK_DEBUG
                #if CHINESE_SUPPORT
                    printf("[调试]解析到ID:%d\r\n", *id);
                #else
                    printf("[Debug] Parsed ID: %d\r\n", *id);
                #endif
                fflush(stdout);
            #endif
            return true;
        }
    }
    else{
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[调试]未解析到有效ID\r\n");
            #else
                printf("[Debug] No valid ID parsed\r\n");
            #endif
            fflush(stdout);
        #endif
        return false;
    }
}

#if TSK_CMD_SWITCH

/**
 * @brief        // 命令和参数解析
 * @param[in]    // analy_p      : 指向任务解析器结构体的指针
 * @param[in]    // data_pointer : 数据指针
 * @param[in]    // parsed       : 解析结果结构体指针
 * @return       // bool : true表示解析成功,false表示解析失败
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
static bool tsk_analy_parsed(tsk_analy_t *analy_p,int* data_pointer,tsk_Parsed_t* parsed){
    tsk_Parsed_t parsed_k;//用于识别,省去清理原结构体参数
    parsed_k.id=parsed->id;
    char str[TSK_MAX_STRING_LEN]={0};
    char str_float[20]={0};
    int str_pointer=0;
    int str_float_pointer=0;

    int symbol_len=0;

    uint8_t point_flag=0;
    uint8_t cmd_fing=0;

    int parsed_count=0;
    //大循环识别
    while (analy_p->data[*data_pointer]!='\0'&&analy_p->data[*data_pointer]!=TSK_ID_SPLIT){
        str_pointer=0;
        str[str_pointer]='\0';  //清理标记
        symbol_len=*data_pointer;//记录位置
        while(tsk_ifchar_float(analy_p->data[*data_pointer],false)){
            str[str_pointer++]=tsk_toupper(analy_p->data[*data_pointer]);//转化为小写进行判断
            (*data_pointer)++;
            //超出后无视后续字符
            if(str_pointer>=TSK_MAX_STRING_LEN){
                while(tsk_ifchar_float(analy_p->data[*data_pointer],false)){
                    (*data_pointer)++;
                }
                break;
            }
        }
        if(str[str_pointer-1]=='='){
            str_pointer--;//等号不属于命令忽略
        }
        str[str_pointer]='\0';//确保数据可用
        if(tsk_seek_id_cmd(&(analy_p->cmdstore),parsed->id,str)){
            if(!cmd_fing){
                cmd_fing=1;
                strcpy(parsed_k.com,(char *)str);
                #if TSK_TASK_DEBUG
                    #if CHINESE_SUPPORT
                        printf("[调试]命令识别:%s\r\n", str);
                    #else
                        printf("[Debug] Command recognized: %s\r\n", str);
                    #endif
                    fflush(stdout);
                #endif
            }
            else{
                if(parsed_count!=0){
                    *data_pointer=symbol_len;//回溯避免命令丢失
                }
                break;
            }
        }
        str_float_pointer=0;
        str_float[str_float_pointer]='\0';//清理字符串
        symbol_len=*data_pointer;//记录位置
        while(tsk_ifchar_float(analy_p->data[*data_pointer],true)){
            if(symbol_len!=*data_pointer&&analy_p->data[*data_pointer]=='-'){
                break;
            }
            if(analy_p->data[*data_pointer]=='.'){
                if(point_flag){
                    point_flag=0;//跳出循环前复位一下
                    break;
                }
                else{
                    point_flag=1;
                }
            }
            str_float[str_float_pointer++]=analy_p->data[*data_pointer];
            (*data_pointer)++;
            if(str_float_pointer>=20){
                while (tsk_ifchar_float(analy_p->data[*data_pointer],true)){
                    (*data_pointer)++;//无视
                }
                break;
            }
        }
        if(symbol_len==*data_pointer){
            //无数据
            break;
        }
        str_float[str_float_pointer]='\0';
        //已经到达最大数据,不进行处理，避免出错
        if(parsed_count>=TSK_MAX_DATALEN){
            while(tsk_ifchar_float(analy_p->data[*data_pointer],true)){
                (*data_pointer)++;
            }
            break;
        }
        parsed_k.data[parsed_count++]=atof(str_float);
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[调试]参数解析: %s -> %.2f\r\n", str_float, parsed_k.data[parsed_count-1]);
            #else
                printf("[Debug] Param parsed: %s -> %.2f\r\n", str_float, parsed_k.data[parsed_count-1]);
            #endif
            fflush(stdout);
        #endif
    }
    if(parsed_count>0){
        memcpy(parsed, &parsed_k, sizeof(tsk_Parsed_t));//数据替换
        return true;
    }
    else{
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[调试]未解析到有效参数\r\n");
            #else
                printf("[Debug] No valid param parsed\r\n");
            #endif
            fflush(stdout);
        #endif
        return false;
    }
}

#else

/**
 * @brief        // 参数解析
 * @param[in]    // analy_p      : 指向任务解析器结构体的指针
 * @param[in]    // data_pointer : 数据指针
 * @param[in]    // parsed       : 解析结果结构体指针
 * @return       // bool : true表示解析成功,false表示解析失败
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
static bool tsk_analy_parsed(tsk_analy_t *analy_p,int* data_pointer,tsk_Parsed_t* parsed){
    //不支持命令解析,直接解析参数
    tsk_Parsed_t parsed_k;//用于识别,省去清理原结构体参数
    parsed_k.id=parsed->id;
    char str_float[20]={0};
    int str_float_pointer=0;

    uint8_t point_flag=0;

    int parsed_count=0;
    //大循环识别
    while (analy_p->data[*data_pointer]!='\0'&&analy_p->data[*data_pointer]!=TSK_ID_SPLIT){
        while (tsk_ifchar_float(analy_p->data[*data_pointer],false)){
            (*data_pointer)++;//跳过非数据部分
        }
        str_float_pointer=0;
        str_float[str_float_pointer]='\0';//清理字符串
        int symbol_len=*data_pointer;//记录位置
        while(tsk_ifchar_float(analy_p->data[*data_pointer],true)){
            if(symbol_len!=*data_pointer&&analy_p->data[*data_pointer]=='-'){
                break;
            }
            if(analy_p->data[*data_pointer]=='.'){
                if(point_flag){
                    point_flag=0;//跳出循环前复位一下
                    break;
                }
                else{
                    point_flag=1;
                }
            }
            str_float[str_float_pointer++]=analy_p->data[*data_pointer];
            (*data_pointer)++;
            if(str_float_pointer>=20){
                while (tsk_ifchar_float(analy_p->data[*data_pointer],true)){
                    (*data_pointer)++;//无视
                }
                break;
            }
        }
        if(symbol_len==*data_pointer){
            //无数据
            break;
        }
        str_float[str_float_pointer]='\0';
        //已经到达最大数据,不进行处理，避免出错
        if(parsed_count>=TSK_MAX_DATALEN){
            while(tsk_ifchar_float(analy_p->data[*data_pointer],true)){
                (*data_pointer)++;
            }
            break;
        }
        parsed_k.data[parsed_count++]=atof(str_float);
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[调试]参数解析: %s -> %.2f\r\n", str_float, parsed_k.data[parsed_count-1]);
            #else
                printf("[Debug] Param parsed: %s -> %.2f\r\n", str_float, parsed_k.data[parsed_count-1]);
            #endif
            fflush(stdout);
        #endif
    }
    if(parsed_count>0){
        memcpy(parsed, &parsed_k, sizeof(tsk_Parsed_t));//数据替换
        return true;
    }
    else{
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[调试]未解析到有效参数\r\n");
            #else
                printf("[Debug] No valid param parsed\r\n");
            #endif
            fflush(stdout);
        #endif
        return false;
    }
}
#endif

/**
 * @brief        // 解析数据并推送任务
 * @param[in]    // analy_p : 指向任务解析器结构体的指针
 * @param[in]    // sched   : 指向任务调度器结构体的指针
 * @return       // void
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
static void tsk_analy_data(tsk_analy_t *analy_p,tsk_TaskScheduler *sched){
    tsk_Parsed_t parsed;
    int data_pointer=0;
    //整个字符串进行解析
    while(analy_p->data[data_pointer]!='\0'){
        if(!tsk_analy_getid(analy_p,&data_pointer,&parsed.id)){
            #if TSK_TASK_DEBUG
                #if CHINESE_SUPPORT
                    printf("[错误]ID解析失败\r\n");
                #else
                    printf("[Error] ID parse failed\r\n");
                #endif
                fflush(stdout);
            #endif
            break;
        }
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[调试]开始命令参数解析,ID=%d\r\n", parsed.id);
            #else
                printf("[Debug] Start command/param parse, ID=%d\r\n", parsed.id);
            #endif
            fflush(stdout);
        #endif
        while(analy_p->data[data_pointer]!='\0'&&analy_p->data[data_pointer]!=TSK_ID_SPLIT){
            if(tsk_analy_parsed(analy_p,&data_pointer,&parsed)){
                if(!(tsk_Push_task(sched,parsed)==TSK_TASK_OK)){
                    #if TSK_TASK_DEBUG
                        #if CHINESE_SUPPORT
                            printf("[错误]任务推送失败\r\n");
                        #else
                            printf("[Error] Task push failed\r\n");
                        #endif
                        fflush(stdout);
                    #endif
                    break;
                }else{
                    #if TSK_TASK_DEBUG
                        #if CHINESE_SUPPORT
                            printf("[调试]任务推送成功,ID=%d\r\n", parsed.id);
                        #else
                            printf("[Debug] Task push success, ID=%d\r\n", parsed.id);
                        #endif
                        fflush(stdout);
                    #endif
                }
            }
            else{
                #if TSK_TASK_DEBUG
                    #if CHINESE_SUPPORT
                        printf("[错误]命令参数解析失败\r\n");
                    #else
                        printf("[Error] Command/param parse failed\r\n");
                    #endif
                    fflush(stdout);
                #endif
                break;
            }
        }
        if(analy_p->data[data_pointer]==TSK_ID_SPLIT){
            data_pointer++;//跳过id分隔符
        }
    }
    analy_p->len=0;//清理缓存
    memset(analy_p->data,0,sizeof(analy_p->data));
}

/**
 * @brief        // 初始化任务解析器
 * @param[in]    // analy_p : 指向任务解析器结构体的指针
 * @return       // void
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
void tsk_analy_Init(tsk_analy_t *analy_p){
    memset(analy_p,0,sizeof(tsk_analy_t));
    tsk_analy_Queue_Init(&analy_p->analy_Queue);
    #if TSK_CMD_SWITCH
        tsk_cmdstore_Init(&analy_p->cmdstore);
    #endif
    #if TSK_TASK_DEBUG
        #if CHINESE_SUPPORT
            printf("[解析器]初始化完成,解析器:%p\r\n",analy_p);
        #else
            printf("[Analyzer] Initialized, Analyzer:%p\r\n",analy_p);
        #endif
        fflush(stdout);
    #endif
}

/**
 * @brief        // 处理解析队列数据
 * @param[in]    // analy_p : 指向任务解析器结构体的指针
 * @param[in]    // sched   : 指向任务调度器结构体的指针
 * @return       // void
 * @note         // 无
 * @author       // 小傲
 * @date         // 2025-09-11
 */
void tsk_dis_data(tsk_analy_t *analy_p,tsk_TaskScheduler *sched){
    if(!sched->isInit){
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[错误]调度器未初始化,调度器:%p\r\n",sched);
            #else
                printf("[Error] Scheduler not initialized, Scheduler:%p\r\n",sched);
            #endif
            fflush(stdout);
        #endif
        return;
    }
    if(analy_p->analy_Queue.count==0){
        return;//无数据,避免过多的调试信息此处不打印
    }
    int queue_len=analy_p->analy_Queue.count;//获取数据长度
    int batch_size;
    //处理决策
    if(queue_len>TSK_CRITICAL_WATERMARK){
        batch_size=TSK_MAX_NORMAL_QUEUE_LEN;
    }
    else if (queue_len>TSK_HIGH_WATERMARK){
        float factor=(queue_len-TSK_LOW_WATERMARK)/(TSK_HIGH_WATERMARK-TSK_LOW_WATERMARK);
        batch_size=TSK_MIN_BATCH_SIZE+factor*(TSK_MAX_BATCH_SIZE-TSK_MIN_BATCH_SIZE);
    }
    else{
        batch_size=TSK_MIN_BATCH_SIZE;
    }
    #if TSK_TASK_DEBUG
        #if CHINESE_SUPPORT
            printf("[调试]本次批量处理数量:%d\r\n", batch_size);
        #else
            printf("[Debug] Batch process count: %d\r\n", batch_size);
        #endif
        fflush(stdout);
    #endif
    //数据处理
    while (!(tsk_is_analy_Queue_Empty(analy_p->analy_Queue)&&batch_size--)){
        if(Tsk_analy_Queue_Pop(&analy_p->analy_Queue,&analy_p->data[analy_p->len])!=TSK_ANALY_QUEUE_OK){
            #if TSK_TASK_DEBUG
                #if CHINESE_SUPPORT
                    printf("[错误]队列弹出失败\r\n");
                #else
                    printf("[Error] Queue pop failed\r\n");
                #endif
                fflush(stdout);
            #endif
            return;
        }
        #if TSK_TASK_DEBUG
            #if CHINESE_SUPPORT
                printf("[调试]弹出数据:%c, 当前缓存长度:%d\r\n", analy_p->data[analy_p->len], analy_p->len+1);
            #else
                printf("[Debug] Pop data: %c, cache len: %d\r\n", analy_p->data[analy_p->len], analy_p->len+1);
            #endif
            fflush(stdout);
        #endif
        analy_p->len++;
        if(analy_p->len>=TSK_ANALY_CACHE_MAXLEN){
            #if TSK_TASK_DEBUG
                #if CHINESE_SUPPORT
                    printf("[警告]解析缓存溢出\r\n");
                #else
                    printf("[Warning] Analyze cache overflow\r\n");
                #endif
                fflush(stdout);
            #endif
            break;//防止溢出
        }
        if(tsk_movgetdata(analy_p->data,TSK_DATA_HEAD,TSK_DATA_TAIL)){
            tsk_analy_data(analy_p,sched);//进行解析;需要点性能解析
        }//数据解析，解析完成后跳出循环
    }
}

#endif 
